package com.xrf;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.system.as.application.system.basics.menu.entity.AsMenuEntity;
import com.system.as.application.system.basics.menu.entity.LinkMenuCompoEntity;
import com.system.as.application.system.basics.menu.mapper.AsMenuMapper;
import com.system.as.application.system.basics.role.entity.LinkRoleMenuEntity;
import com.system.as.application.system.basics.role.service.LinkRoleMenuService;
import com.system.as.application.system.request.compo.ReqCompoFunc;
import com.system.core.common.EnumCode;
import com.system.core.common.ResultView;
import com.system.core.common.base.SystemServiceImpl;
import com.system.core.common.session.SessionMenu;
import com.system.core.tool.ToolTime;

@Service
public class AsMenuService extends SystemServiceImpl<AsMenuMapper, AsMenuEntity> {
    @Autowired
    private AsMenuMapper asMenuMapper;
    
    @Autowired
    private LinkRoleMenuService linkRoleMenuService;
    
    @Autowired
    private LinkMenuCompoService linkMenuCompoService;
    
    private static Logger logger = LoggerFactory.getLogger(AsMenuService.class);
    
    @Transactional
    public ResultView insert(String menuName) {
        ResultView view = new ResultView(EnumCode.SUCCESS);
        if (StringUtils.isBlank(menuName)) {
            view.setCode(EnumCode.ERROR_10002);
            return view;
        }
        if (isExist(null, menuName)) {
            view.setCode(EnumCode.ERROR_9999);
            return view;
        }
        AsMenuEntity entity = new AsMenuEntity();
        entity.setMenuName(menuName);
        save(entity);
        view.setData(entity);
        return view;
    }
    
    public List<AsMenuEntity> selectListByRoleId(List<String> roleIdList) {
        List<AsMenuEntity> list = null;
        if (null != roleIdList && roleIdList.size() > 0) {
            List<LinkRoleMenuEntity> _list = linkRoleMenuService.selectListByRoleId(roleIdList);
            if (_list == null) {
                return list;
            }
            Set<String> menuIdList = new HashSet<String>();
            _list.forEach(_link -> {
                menuIdList.add(_link.getMenuId());
            });
            if (null != menuIdList && menuIdList.size() > 0) {
                QueryWrapper<AsMenuEntity> queryWrapper = new QueryWrapper<AsMenuEntity>();
                queryWrapper.in("MENU_ID", menuIdList);
                list = asMenuMapper.selectList(queryWrapper);
            }
        }
        return list;
    }
    
    public List<AsMenuEntity> selectListByRoleId(String roleId) {
        if (StringUtils.isBlank(roleId)) {
            return null;
        }
        List<AsMenuEntity> list = asMenuMapper.selectListByRoleId(roleId);
        return list;
    }
    
    public List<AsMenuEntity> selectListByMenuId(Set<String> menuIdList) {
        List<AsMenuEntity> list = null;
        if (null != menuIdList && menuIdList.size() > 0) {
            QueryWrapper<AsMenuEntity> queryWrapper = new QueryWrapper<AsMenuEntity>();
            queryWrapper.in("MENU_ID", menuIdList);
            queryWrapper.orderByAsc(" ORD_INDEX ");// 正序
            list = asMenuMapper.selectList(queryWrapper);
        }
        return list;
    }
    
    public List<AsMenuEntity> selectListByParentId(String parentId, List<SessionMenu> userMenus) {
        if (userMenus == null || userMenus.size() == 0) {
            return null;
        }
        List<AsMenuEntity> list = null;
        QueryWrapper<AsMenuEntity> queryWrapper = new QueryWrapper<AsMenuEntity>();
        if (StringUtils.isNotBlank(parentId))
            queryWrapper.eq("PARENT_ID", parentId);
        List<String> menuIdList = new ArrayList<String>();
        userMenus.forEach(menu -> {
            menuIdList.add(menu.getMenuId());
        });
        queryWrapper.in("MENU_ID", menuIdList);
        queryWrapper.orderByAsc(" PARENT_ID,ORD_INDEX ");
        list = asMenuMapper.selectList(queryWrapper);
        return list;
    }
    
    public List<AsMenuEntity> selectListByParentId(String parentId) {
        List<AsMenuEntity> list = null;
        QueryWrapper<AsMenuEntity> queryWrapper = new QueryWrapper<AsMenuEntity>();
        if (StringUtils.isNotBlank(parentId)) {
            queryWrapper.eq("PARENT_ID", parentId);
        }
        queryWrapper.orderByAsc(" PARENT_ID,ORD_INDEX ");
        list = asMenuMapper.selectList(queryWrapper);
        return list;
    }
    
    @Transactional
    public boolean savePerminssion(String menuId, List<LinkMenuCompoEntity> list) {
        boolean flag = false;
        if (StringUtils.isBlank(menuId)) {
            return flag;
        }
        flag = linkMenuCompoService.deleteListByMenuId(menuId);
        if (null != list && list.size() > 0) {
            flag = linkMenuCompoService.saveBatch(list);
        }
        return flag;
    }
    
    @Transactional
    public boolean saveAuth(String roleId, String menuId, List<ReqCompoFunc> list) throws Exception {
        linkRoleMenuService.deleteListByRoleIdAndMenuId(roleId, menuId);
        if (null != list && list.size() > 0) {
            List<LinkRoleMenuEntity> insertList = new ArrayList<LinkRoleMenuEntity>();
            list.forEach(_req -> {
                LinkRoleMenuEntity link = new LinkRoleMenuEntity();
                if (StringUtils.equals("F", _req.getCompoType())) {
                    link.setCompoId(_req.getParentId());
                } else {
                    link.setCompoId(_req.getCompoId());
                }
                link.setFuncId(_req.getFuncId());
                link.setMenuId(_req.getMenuId());
                link.setRoleId(roleId);
                link.setTransDate(ToolTime.getNowDate());
                insertList.add(link);
            });
            linkRoleMenuService.saveBatch(insertList);
        }
        return true;
    }
    
    public List<SessionMenu> selectMenuListByRoleId(List<String> roleId) {
        return asMenuMapper.selectMenuListByRoleId(roleId);
    }
    
    public Map<String, Set<String>> selectPermissionListByRoleId(List<String> roleIdList) {
        Map<String, Set<String>> permissionMap = new HashMap<String, Set<String>>();
        List<LinkRoleMenuEntity> _linkRoleMenuList = linkRoleMenuService.selectListByRoleId(roleIdList);
        if (null != _linkRoleMenuList && _linkRoleMenuList.size() > 0) {
            _linkRoleMenuList.forEach(_link -> {
                String key = _link.getCompoId();
                Set<String> funcList = permissionMap.get(key);
                if (null == funcList)
                    funcList = new HashSet<String>();
                funcList.add(_link.getFuncId());
                permissionMap.put(_link.getCompoId(), funcList);
            });
        }
        return permissionMap;
    }
    
    @Transactional
    public boolean deleteByMenuId(String menuId) {
        if (StringUtils.isBlank(menuId)) {
            return true;
        }
        linkRoleMenuService.deleteListByMenuId(menuId);
        linkMenuCompoService.deleteListByMenuId(menuId);
        removeById(menuId);
        return true;
    }
    
    @Transactional
    public ResultView update(String menuId, String menuName) {
        ResultView view = new ResultView(EnumCode.SUCCESS);
        if (isExist(menuId, menuName)) {
            view.setCode(EnumCode.ERROR_9999);
            return view;
        }
        AsMenuEntity entity = new AsMenuEntity();
        entity.setMenuId(menuId);
        entity.setMenuName(menuName);
        updateById(entity);
        return view;
    }
    
    private boolean isExist(String menuId, String menuName) {
        List<AsMenuEntity> list = selectListByMenuName(menuName);
        if (list != null) {
            if (list.size() > 1) {
                return true;
            } else if (list.size() == 1) {
                AsMenuEntity entity = list.get(0);
                if (!StringUtils.equalsAnyIgnoreCase(entity.getMenuId(), menuId)) {
                    return true;
                }
            }
        }
        return false;
    }
    
    public List<AsMenuEntity> selectListByMenuName(String menuName) {
        QueryWrapper<AsMenuEntity> queryWrapper = new QueryWrapper<AsMenuEntity>();
        queryWrapper.eq("MENU_NAME", menuName);
        List<AsMenuEntity> list = list(queryWrapper);
        return list;
    }
}